package mallcart

import (
	"context"
	"fmt"
	"strconv"

	"mall/common/jwt"
	"mall/common/resultx"
	"mall/service/backend/common/utils/pointy"
	"mall/service/forum/api/internal/lib/shoppingcart"
	"mall/service/forum/api/internal/svc"
	"mall/service/forum/api/internal/types"
	"mall/service/order/rpc/orderclient"
	"mall/service/product/rpc/productclient"

	"github.com/sirupsen/logrus"
	"github.com/zeromicro/go-zero/core/logx"
)

type UpdateShoppingCartLogic struct {
	logx.Logger
	ctx    context.Context
	svcCtx *svc.ServiceContext
}

func NewUpdateShoppingCartLogic(ctx context.Context, svcCtx *svc.ServiceContext) *UpdateShoppingCartLogic {
	return &UpdateShoppingCartLogic{
		Logger: logx.WithContext(ctx),
		ctx:    ctx,
		svcCtx: svcCtx,
	}
}

func (l *UpdateShoppingCartLogic) UpdateShoppingCart(
	req *types.UpdateShoppingCartReq,
	headers *[]*types.Header,
) (resp *types.BaseMsgResp, err error) {
	userId := jwt.GetUserId(l.ctx)
	if userId == 0 {
		return nil, resultx.NewErrCode(resultx.TOKEN_EXPIRE_ERROR)
	}

	if len(req.Items) == 0 {
		return nil, resultx.NewErrCode(resultx.PRODUCT_VARIATION_ID_REQUIRED)
	}

	skuIdQtyMap := make(map[uint64]uint32)
	for _, v := range req.Items {
		if v.SkuId != nil && v.Quantity != nil && *v.SkuId > 0 {
			if num, ok := skuIdQtyMap[*v.SkuId]; !ok {
				skuIdQtyMap[*v.SkuId] = *v.Quantity
			} else {
				skuIdQtyMap[*v.SkuId] = num + *v.Quantity
			}
		}
	}
	var stocks []*productclient.ProductVariationStock
	for skuId, qty := range skuIdQtyMap {
		if qty == 0 {
			continue
		}

		stocks = append(stocks, &productclient.ProductVariationStock{
			Id:    skuId,
			Stock: qty,
		})
	}
	if len(stocks) > 0 {
		res, err := l.svcCtx.ProductRpc.CheckAndSubtractStock(l.ctx, &productclient.CheckAndSubtractStockReq{
			Data:      stocks,
			CheckOnly: pointy.GetPointer(uint32(1)),
		})
		if err != nil {
			logx.Errorw("UpdateShoppingCart CheckAndSubtractStock err", logx.Field("detail", err.Error()))
			// return &types.BaseMsgResp{
			// 	Msg: "修改失败，库存不足",
			// }, nil
			return nil, resultx.NewErrCode(resultx.UPDATE_CART_ITEM_FAILED)
		}

		logrus.Info(fmt.Sprintf("UpdateShoppingCart CheckAndSubtractStock res: %+v", res))
		if len(res.Msg) > 0 {
			// return &types.BaseMsgResp{
			// 	Msg: "修改失败，库存不足，Sku Id: " + res.Msg,
			// }, nil
			return nil, resultx.NewErrCode(resultx.UPDATE_CART_ITEM_FAILED)
		}
	}

	shoppingCart := shoppingcart.NewShoppingCart(l.ctx, l.svcCtx, "forum:cart")
	skuQtyMap := make(map[uint64]*orderclient.ShoppingCartSpecialInfo)
	for skuId, qty := range skuIdQtyMap {
		if qty > 0 {
			_, err = shoppingCart.UpdateNumber(strconv.FormatInt(int64(userId), 10), strconv.FormatInt(int64(skuId), 10), int64(qty))
			if err != nil {
				return nil, err
			}

			skuQtyMap[skuId] = &orderclient.ShoppingCartSpecialInfo{
				Quantity: pointy.GetPointer(qty),
			}
		} else {
			_, err = shoppingCart.Delete(strconv.FormatInt(int64(userId), 10), strconv.FormatInt(int64(skuId), 10))
			if err != nil {
				return nil, err
			}

			skuQtyMap[skuId] = &orderclient.ShoppingCartSpecialInfo{
				Quantity: pointy.GetPointer(qty),
			}
		}
	}

	_, err = l.svcCtx.OrderRpc.BatchUpdateShoppingCart(l.ctx, &orderclient.BatchUpdateShoppingCartReq{
		SkuQtyMap: skuQtyMap,
		UserId:    pointy.GetPointer(userId),
	})
	if err != nil {
		logx.Errorw("UpdateShoppingCart BatchUpdateShoppingCart err", logx.Field("detail", err.Error()))
		return &types.BaseMsgResp{
			Msg: "修改失败",
		}, nil
	}

	return &types.BaseMsgResp{}, nil
}
